﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using CommServer.Upgrade;
using System.IO;
using System.Collections;
using CommServer.Common.Database;
using CommServer.Network;

// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace CommServer.Controllers
{
    public class upgradeController : Controller
    {
        // GET: /<controller>/
        //public IActionResult Index()
        //{
        //    return View();
        //}
        [HttpPost]
        public DbResult<dynamic> queryStatus(string RtuSN, bool forceQuery = false)
        {
            DbResult<dynamic> Result = new DbResult<dynamic>();
            upgradeInv inv = null;
            byte[] bUserId;
            if (!HttpContext.Session.TryGetValue("UserId", out bUserId))
            {
                Result.state = (int)ErrorCode.NoLogin;
                Result.errMsg = "用户未登录";
                return Result;
            }
            byte[] bRole;
            if (!HttpContext.Session.TryGetValue("UserRole", out bRole))
            {
                Result.state = (int)ErrorCode.NoLogin;
                Result.errMsg = "用户未登录";
                return Result;
            }
            if (BitConverter.ToInt32(bRole, 0) > 0)
            {
                Result.state = (int)ErrorCode.NoAuth;
                Result.errMsg = "用户无权限，只有管理员才能升级！";
                return Result;
            }
            lock ((Program.upgradeInvs as ICollection).SyncRoot)
            {
                if (Program.upgradeInvs.TryGetValue(RtuSN, out inv))
                {
                    if (inv == null)
                    {
                        Result.state = (int)ErrorCode.NoUpgrade;
                        Result.errMsg = "没有升级过程！";
                        return Result;
                    }
                    else
                    {
                        Result.state = 0;
                        Result.errMsg = "";
                        if (forceQuery)
                        {
                            inv.TotalRetryCount = 0;
                            inv.StepRetryCount = 0;
                            inv.queryStatus();
                        }

                        Result.data = new { total = inv.TotalBlocks, current = inv.CurrentBlockNo, step = inv.Step, complete = inv.Completed, msg = inv.ErrorMsg };

                    }
                }
                else
                {
                    Result.state = (int)ErrorCode.NoUpgrade;
                    Result.errMsg = "没有升级过程！";
                    return Result;
                }
            }
            return Result;
        }
        [HttpPost]
        public DbResult cancelInv(string RtuSN)
        {
            DbResult Result = new DbResult();
            upgradeInv Inv = null;
            lock ((Program.upgradeInvs as ICollection).SyncRoot)
            {
                if (Program.upgradeInvs.TryGetValue(RtuSN, out Inv))
                {
                    if (Inv != null)
                    {
                        Inv.cancelUpgrade();
                    }
                }
            }
            Result.state = 0;

            return Result;
        }
        [HttpPost]
        public DbResult cancelDev(string RtuSN)
        {
            
            DbResult Result = new DbResult();
            upgradeDevice Dev = null;
            if (RtuSN == null)
            {
                Result.errMsg = "设备序列号为空!";
                return Result;
            }
            lock ((Program.upgradeDevs as ICollection).SyncRoot)
            {
                if (Program.upgradeDevs.TryGetValue(RtuSN, out Dev))
                {
                    if (Dev != null)
                    {
                        Dev.cancelUpgrade();
                    }
                }
            }
            Result.state = 0;

            return Result;
        }
        [HttpPost]
        public DbResult<dynamic> UpgradeInv(string RtuSN, IFormFile img, bool forceUpdate = false, bool closeLastUpdate = false)
        {
            DbResult<dynamic> Result = new DbResult<dynamic>();
            if (img == null)
            {
                Result.state = (int)ErrorCode.ParamIncorrect;
                Result.errMsg = "文件为空！";
                return Result;
            }
            byte[] bUserId;
            if (!HttpContext.Session.TryGetValue("UserId", out bUserId))
            {
                Result.state = (int)ErrorCode.NoLogin;
                Result.errMsg = "用户未登录";
                return Result;
            }
            byte[] bRole;
            if (!HttpContext.Session.TryGetValue("UserRole", out bRole))
            {
                Result.state = (int)ErrorCode.NoLogin;
                Result.errMsg = "用户未登录";
                return Result;
            }
            if (BitConverter.ToInt32(bRole, 0) > 0)
            {
                Result.state = (int)ErrorCode.NoAuth;
                Result.errMsg = "用户无权限，只有管理员才能升级！";
                return Result;
            }
            if (Program.GetDeviceServer().GetSession(RtuSN) == null)
            {
                Result.state = (int)ErrorCode.NotConnect;
                Result.errMsg = "设备不在线！";
                return Result;
            }
            string Path = Directory.GetCurrentDirectory() + @"\wwwroot\InvImage\";
            if (!Directory.Exists(Path))
            {
                Directory.CreateDirectory(Path);
            }
            string FileName = Path + Guid.NewGuid().ToString("N") + ".img";
            MemoryStream stream = new MemoryStream();
            img.CopyTo(stream);
            byte[] fileContents = stream.ToArray();
            System.IO.File.WriteAllBytes(FileName, fileContents);
            stream.Dispose();
            int Cs = 0;
            for (int i = 0; i < fileContents.Length; i++)
            {
                Cs = Cs + fileContents[i];
            }
            Cs = Cs & 0xffff;
            upgradeInv Inv = null;
            lock ((Program.upgradeInvs as ICollection).SyncRoot)
            {
                if (Program.upgradeInvs.TryGetValue(RtuSN, out Inv))
                {//如果已经存在当前逆变器的升级，则对比文件CS，CS不对，则认为不是同一个升级，
                    if (Inv.FileCS != Cs)
                    {
                        if (!forceUpdate)
                        {
                            Result.state = (int)ErrorCode.FileError;
                            Result.errMsg = "已经有一个升级，而且与当前文件不同！若要强制升级，则请使用强制升级命令！";
                            return Result;
                        }
                        else
                        {
                            Inv.FileName = FileName;
                            Inv.loadFile();
                            Inv.startUpgrade(true);
                            Result.state = 0;
                            Result.errMsg = "";
                            Result.data = new { total = Inv.TotalBlocks, current = Inv.CurrentBlockNo, step = Inv.Step, complete = Inv.Completed, msg = Inv.ErrorMsg, fileCs = Inv.FileCS };
                        }
                    }
                    else
                    {
                        Result.state = 0;
                        Result.errMsg = "";
                        //Inv.startUpgrade(true);
                        Inv.Upgrading = true;
                        Inv.Completed = false;
                        Inv.StepRetryCount = 0;
                        Inv.TotalRetryCount = 0;
                        if (closeLastUpdate)
                        {
                            Inv.startUpgrade(true);
                        }
                        else
                            Inv.queryStatus();
                        Result.data = new { total = Inv.TotalBlocks, current = Inv.CurrentBlockNo, step = Inv.Step, complete = Inv.Completed, msg = Inv.ErrorMsg, fileCs = Inv.FileCS };
                        return Result;
                    }
                }
                else
                {
                    Inv = new upgradeInv(RtuSN, FileName);
                    Inv.loadFile();

                    Inv.startUpgrade(closeLastUpdate);
                    Result.state = 0;
                    Result.errMsg = "";
                    Result.data = new { total = Inv.TotalBlocks, current = Inv.CurrentBlockNo, step = Inv.Step, complete = Inv.Completed, msg = Inv.ErrorMsg, fileCs = Inv.FileCS };
                    Program.upgradeInvs.Add(RtuSN, Inv);
                }
            }
            return Result;
        }
        [HttpPost]
        public DbResult<dynamic> queryDevStatus(string RtuSN, bool forceQuery = false)
        {
            DbResult<dynamic> Result = new DbResult<dynamic>();
            upgradeDevice dev = null;
            byte[] bUserId;
            if (!HttpContext.Session.TryGetValue("UserId", out bUserId))
            {
                Result.state = (int)ErrorCode.NoLogin;
                Result.errMsg = "用户未登录";
                return Result;
            }
            byte[] bRole;
            if (!HttpContext.Session.TryGetValue("UserRole", out bRole))
            {
                Result.state = (int)ErrorCode.NoLogin;
                Result.errMsg = "用户未登录";
                return Result;
            }
            if (BitConverter.ToInt32(bRole, 0) > 0)
            {
                Result.state = (int)ErrorCode.NoAuth;
                Result.errMsg = "用户无权限，只有管理员才能升级！";
                return Result;
            }
            lock ((Program.upgradeDevs as ICollection).SyncRoot)
            {
                if (Program.upgradeDevs.TryGetValue(RtuSN, out dev))
                {
                    if (dev == null)
                    {
                        Result.state = (int)ErrorCode.NoUpgrade;
                        Result.errMsg = "没有升级过程！";
                        return Result;
                    }
                    else
                    {
                        Result.state = 0;
                        Result.errMsg = "";
                        if (forceQuery)
                        {
                            dev.TotalRetryCount = 0;
                            dev.StepRetryCount = 0;
                            dev.queryStatus();
                        }

                        Result.data = new { total = dev.TotalBlocks, current = dev.CurrentBlockNo, step =0, complete = dev.Completed, msg = dev.ErrorMsg };

                    }
                }
                else
                {
                    Result.state = (int)ErrorCode.NoUpgrade;
                    Result.errMsg = "没有升级过程！";
                    return Result;
                }
            }
            return Result;
        }

        [HttpPost]
        public DbResult<dynamic> UpgradeDev(string RtuSN, IFormFile img, bool forceUpdate = false, bool closeLastUpdate = false)
        {
            DbResult<dynamic> Result = new DbResult<dynamic>();
            if (img == null)
            {
                Result.state = (int)ErrorCode.ParamIncorrect;
                Result.errMsg = "文件为空！";
                return Result;
            }
            byte[] bUserId;
            if (!HttpContext.Session.TryGetValue("UserId", out bUserId))
            {
                Result.state = (int)ErrorCode.NoLogin;
                Result.errMsg = "用户未登录";
                return Result;
            }
            byte[] bRole;
            if (!HttpContext.Session.TryGetValue("UserRole", out bRole))
            {
                Result.state = (int)ErrorCode.NoLogin;
                Result.errMsg = "用户未登录";
                return Result;
            }
            if (BitConverter.ToInt32(bRole, 0) > 0)
            {
                Result.state = (int)ErrorCode.NoAuth;
                Result.errMsg = "用户无权限，只有管理员才能升级！";
                return Result;
            }
            if (Program.GetDeviceServer().GetSession(RtuSN) == null)
            {
                Result.state = (int)ErrorCode.NotConnect;
                Result.errMsg = "设备不在线！";
                return Result;
            }
            string Path = Directory.GetCurrentDirectory() + @"\wwwroot\DevImage\";
            if (!Directory.Exists(Path))
            {
                Directory.CreateDirectory(Path);
            }
            string FileName = Path + Guid.NewGuid().ToString("N") + ".img";
            MemoryStream stream = new MemoryStream();
            img.CopyTo(stream);
            byte[] fileContents = stream.ToArray();
            System.IO.File.WriteAllBytes(FileName, fileContents);
            stream.Dispose();
            int Cs = 0;
            for (int i = 0; i < fileContents.Length; i++)
            {
                Cs = (Cs + fileContents[i]) & 0xffff;
            }
            Cs = Cs & 0xffff;
            upgradeDevice device = null;
            lock ((Program.upgradeDevs as ICollection).SyncRoot)
            {
                if (Program.upgradeDevs.TryGetValue(RtuSN, out device))
                {//如果已经存在当前逆变器的升级，则对比文件CS，CS不对，则认为不是同一个升级，
                    if (device.FileCS != Cs)
                    {
                        if (!forceUpdate)
                        {
                            Result.state = (int)ErrorCode.FileError;
                            Result.errMsg = "已经有一个升级，而且与当前文件不同！若要强制升级，则请使用强制升级命令！";
                            return Result;
                        }
                        else
                        {
                            device.FileName = FileName;
                            device.loadFile(FileName);
                            device.startUpgrade(true);
                            Result.state = 0;
                            Result.errMsg = "";
                            Result.data = new { total = device.TotalBlocks, current = device.CurrentBlockNo, step = 0, complete = device.Completed, msg = device.ErrorMsg, fileCs = device.FileCS };
                        }
                    }
                    else
                    {
                        Result.state = 0;
                        Result.errMsg = "";
                        //Inv.startUpgrade(true);
                        device.Upgrading = true;
                        device.Completed = false;
                        device.StepRetryCount = 0;
                        device.TotalRetryCount = 0;
                        device.CurrentBlockNo = 0;
                        if (closeLastUpdate)
                        {
                            device.startUpgrade(true);
                        }
                        else
                            device.queryStatus();
                        Result.data = new { total = device.TotalBlocks, current = device.CurrentBlockNo, step = 0, complete = device.Completed, msg = device.ErrorMsg, fileCs = device.FileCS };
                        return Result;
                    }
                }
                else
                {
                    device = new upgradeDevice(RtuSN, FileName);
                    device.loadFile(FileName);

                    device.startUpgrade(closeLastUpdate);
                    Result.state = 0;
                    Result.errMsg = "";
                    Result.data = new { total = device.TotalBlocks, current = device.CurrentBlockNo, step = 0, complete = device.Completed, msg = device.ErrorMsg, fileCs = device.FileCS };
                    Program.upgradeDevs.Add(RtuSN, device);
                }
            }
            return Result;
        }
    }
}
